﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Medianamik.Globalization.Utilities
{
    public abstract class ResourceExporter<T> 
    {
       public T Export(IEnumerable<string> resourceSets, IMedianamikResourceDataManager manager)
       {
           if (manager == null)
               throw new ArgumentNullException("manager");
           if (resourceSets == null)
               throw new ArgumentNullException("resourceSets");
           if (resourceSets.Count() == 0)
               throw new ArgumentException("There must be at least one resource set to export", "resourceSets");

           var export = CreateInstance();

           foreach (var resourceSet in resourceSets)
           {
                var resources = manager.GetResourceIds(resourceSet);
                foreach (var resourceId in resources)
                {
                    var cultureValues = manager.GetResourceStrings(resourceId, resourceSet);
                    if(LanguagesToExport != null)
                        ExportWithLangs(resourceSet, resourceId, export, cultureValues);
                    else
                        ExportWithoutLangs(resourceSet, resourceId, export, cultureValues);
                }
            }
           return export;
       }

        private void ExportWithoutLangs(string resourceSet, string resourceId, T export, Dictionary<string, string> cultureValues)
        {
            foreach (var cVal in cultureValues)
            {
                if (ResourceDataIsvalid(resourceSet, resourceId, cVal))
                {
                    var resource = new Resource(resourceId, cVal.Key, cVal.Value, resourceSet);
                    AddResource(export, resource);
                }
            }
        }
        private void ExportWithLangs(string resourceSet, string resourceId, T export, Dictionary<string, string> cultureValues)
        {
            var usedLangs = new List<string>();
            var langs = LanguagesToExport.Select(x => x.ToLower());
            bool addedOnce = false;
            foreach (var cVal in cultureValues)
            {
                if (ResourceDataIsvalid(resourceSet, resourceId, cVal) && langs.Contains(cVal.Key.ToLower()))
                {
                    var resource = new Resource(resourceId, cVal.Key, cVal.Value, resourceSet);
                    AddResource(export, resource);
                    usedLangs.Add(cVal.Key.ToLower());
                    addedOnce = true;
                }
            }

            if(addedOnce)
            {
                foreach (var lang in langs)
                {
                    if (!usedLangs.Contains(lang))
                        AddResource(export, new Resource(resourceId, lang, String.Empty, resourceSet));
                }
            }
        }
        private static bool ResourceDataIsvalid(string resourceSet, string resourceId, KeyValuePair<string, string> str)
        {
            return !string.IsNullOrEmpty(resourceId) && !string.IsNullOrEmpty(resourceSet) && !string.IsNullOrEmpty(str.Key) && !string.IsNullOrEmpty(str.Value);
        }

        protected abstract T CreateInstance();
        protected abstract void AddResource(T export, Resource resource);

        public IEnumerable<string> LanguagesToExport
        {
            get;
            set;
        }
        
    }

}
